{
  "name": "Case 76 - Hiring Manager - Job Market Intelligence Tracker",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 * * 1"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -1200,
        -160
      ],
      "id": "1a6b682a-f334-4f48-a937-1bf3a47b9b35",
      "name": "Weekly Schedule - Monday 9 AM"
    },
    {
      "parameters": {
        "actorId": {
          "__rl": true,
          "value": "buIWk2uOUzTmcLsuB",
          "mode": "list",
          "cachedResultName": "Linkedin Post Search Scraper (No Cookies) (harvestapi/linkedin-post-search)",
          "cachedResultUrl": "https://console.apify.com/actors/buIWk2uOUzTmcLsuB/input"
        },
        "customBody": "{\n  \"authorUrls\": [\n    \"https://www.linkedin.com/company/google\",\n    \"https://www.linkedin.com/company/microsoft\",\n    \"https://www.linkedin.com/company/meta\",\n    \"https://www.linkedin.com/company/amazon\",\n    \"https://www.linkedin.com/company/apple\",\n    \"https://www.linkedin.com/company/salesforce\",\n    \"https://www.linkedin.com/company/oracle\",\n    \"https://www.linkedin.com/company/ibm\",\n    \"https://www.linkedin.com/company/adobe\",\n    \"https://www.linkedin.com/company/netflix\"\n  ],\n  \"searchKeywords\": [\n    \"hiring\",\n    \"we're looking for\",\n    \"join our team\",\n    \"now hiring\",\n    \"careers\",\n    \"job opening\"\n  ],\n  \"maxPosts\": 50,\n  \"postedLimit\": \"week\",\n  \"scrapeComments\": false,\n  \"scrapeReactions\": false\n}"
      },
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        -1024,
        -160
      ],
      "id": "5ed270b0-d7a0-4a0e-8c79-b39ea4b1f069",
      "name": "Scrape LinkedIn Job Posts",
      "credentials": {
        "apifyApi": {
          "id": "TXPU4EgOj6rkzr43",
          "name": "Apify account 2"
        }
      }
    },
    {
      "parameters": {
        "resource": "Datasets",
        "datasetId": "={{ $json.defaultDatasetId }}"
      },
      "type": "@apify/n8n-nodes-apify.apify",
      "typeVersion": 1,
      "position": [
        -832,
        -160
      ],
      "id": "394c27b0-62a8-40a1-9f89-866f81023286",
      "name": "Get Dataset Items",
      "credentials": {
        "apifyApi": {
          "id": "w5S6YBbbyUddEfQA",
          "name": "Apify account"
        }
      }
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "GPT-4o-mini"
        },
        "responses": {
          "values": [
            {
              "role": "system",
              "content": "=You are a Job Posting Validation Expert.\n\nAnalyze LinkedIn posts to determine if they are genuine job postings or hiring announcements.\n\nReturn ONLY valid JSON in this exact format:\n{\n  \"is_job_posting\": \"yes|no\",\n  \"confidence\": 0.95,\n  \"reason\": \"brief explanation\"\n}\n\nCriteria for \"yes\" (genuine job posting):\n✅ Announces specific open position with job title\n✅ \"We're hiring for [role]\" messaging\n✅ Lists job requirements or qualifications\n✅ Mentions apply link or application process\n✅ Contains job description details\n✅ Recruiting team posting about open roles\n✅ \"Join our team as [role]\" announcements\n✅ Career page links to specific positions\n\nCriteria for \"no\" (NOT a job posting):\n❌ General \"we're growing\" without specific role\n❌ Employee spotlight or team celebration posts\n❌ Company culture posts without hiring intent\n❌ Metaphorical use of \"hiring\" or \"looking for\"\n❌ Reposting someone else's job search\n❌ Career advice posts\n❌ Recruiting tips for other recruiters\n❌ Alumni updates mentioning jobs casually\n\nRules:\n1. confidence: 0-1 scale (0.9+ for very clear job postings)\n2. reason: 1 sentence explaining the decision\n3. Be strict - require actual hiring intent with specific role\n4. Return ONLY the JSON object, no explanations"
            },
            {
              "content": "=Analyze this LinkedIn post to determine if it's a genuine job posting:\n\nAuthor: {{ $json.author.name }}\nPost Date: {{ $json.postedAt.date }}\nPost Content: {{ $json.content }}\n\nReturn only JSON."
            }
          ]
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 2.1,
      "position": [
        -640,
        -160
      ],
      "id": "3b1a7271-a1a2-4756-8369-72d52fb76048",
      "name": "AI Validation Filter",
      "credentials": {
        "openAiApi": {
          "id": "ICwxUBbatsF2sDvy",
          "name": "OpenAi account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// UNIVERSAL AI RESPONSE PARSER - Same code for ALL cases\nconst items = [];\nconst input = $input.all();\n\nfunction extractJSON(text) {\n  const jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\n  if (!jsonMatch) return null;\n  return jsonMatch[0];\n}\n\ninput.forEach((item, index) => {\n  try {\n    let aiText = item.json.output[0].content[0].text || '';\n    \n    // Clean markdown code blocks\n    aiText = aiText\n      .replace(/```json/gi, '')\n      .replace(/```/g, '')\n      .trim();\n    \n    // Extract JSON object\n    const jsonStr = extractJSON(aiText);\n    \n    if (!jsonStr) {\n      throw new Error('No JSON found in AI response');\n    }\n    \n    // Parse and return clean JSON\n    const parsed = JSON.parse(jsonStr);\n    items.push({ json: parsed });\n    \n  } catch (error) {\n    console.error(`Parse error for item ${index}:`, error.message);\n    // Return empty object on error - no case-specific fields\n    items.push({ json: {} });\n  }\n});\n\nreturn items;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -352,
        -160
      ],
      "id": "ed8a30bd-ab3b-410a-bfc1-893ff4752d40",
      "name": "Parse AI Validation"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "is_job_posting",
              "name": "is_job_posting",
              "value": "={{ $json.is_job_posting }}",
              "type": "string"
            },
            {
              "id": "confidence",
              "name": "confidence",
              "value": "={{ $json.confidence }}",
              "type": "number"
            },
            {
              "id": "reason",
              "name": "reason",
              "value": "={{ $json.reason }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -176,
        -160
      ],
      "id": "d9eec5cc-890c-4767-bb37-b00cd69f5d38",
      "name": "Edit Fields - Validation"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "condition-001",
              "leftValue": "={{ $json.is_job_posting }}",
              "rightValue": "yes",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2,
      "position": [
        32,
        -160
      ],
      "id": "bfb4f3a6-b2bb-42fb-bac6-d6d396707b3b",
      "name": "Filter Only Job Posts"
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "GPT-4o-mini"
        },
        "responses": {
          "values": [
            {
              "role": "system",
              "content": "=You are a Job Market Intelligence Analyst.\n\nExtract structured job posting information from LinkedIn posts.\n\nReturn ONLY valid JSON in this exact format:\n{\n  \"job_title\": \"exact role title\",\n  \"seniority_level\": \"Entry|Mid|Senior|Executive|Unclear\",\n  \"department\": \"Engineering|Sales|Marketing|Operations|Product|Finance|HR|Customer Success|Data|Design|Other\",\n  \"required_skills\": [\"skill 1\", \"skill 2\", \"skill 3\"],\n  \"location_type\": \"Remote|Hybrid|On-site|Not specified\",\n  \"location_city\": \"City name if mentioned, otherwise 'Multiple' or 'Not specified'\",\n  \"urgency_level\": \"Immediate|Normal|Future planning\",\n  \"compensation_mentioned\": \"Yes - [range]|No\",\n  \"competitive_intel\": \"Brief analysis of what this hiring reveals about company strategy (max 150 chars)\"\n}\n\nExtraction Rules:\n1. job_title: Extract exact role name from post\n2. seniority_level: Infer from title/requirements (Director+ = Executive, 5+ years = Senior, 2-5 = Mid, <2 = Entry)\n3. department: Choose most accurate category\n4. required_skills: Extract top 3-5 skills mentioned\n5. location_type: Remote/Hybrid/On-site based on post\n6. location_city: Extract city if mentioned\n7. urgency_level: Based on language (\"ASAP\", \"immediate\" = Immediate)\n8. compensation_mentioned: Include range if stated\n9. competitive_intel: Analyze strategic implications (expansion? new product? scaling?)\n\nReturn ONLY the JSON object, no explanations."
            },
            {
              "content": "=Extract job market intelligence from this LinkedIn post:\n\nCompany: {{ $('Get Dataset Items').item.json.author.name }}\nPost Date: {{ $('Get Dataset Items').item.json.postedAt.date }}\nPost Content: {{ $('Get Dataset Items').item.json.content }}\nEngagement: {{ $('Get Dataset Items').item.json.engagement.likes }} likes, {{ $('Get Dataset Items').item.json.engagement.comments }} comments\n\nReturn only JSON."
            }
          ]
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 2.1,
      "position": [
        192,
        -160
      ],
      "id": "f5cc928d-f269-41b7-bc11-664612327490",
      "name": "AI Extract Job Intelligence",
      "credentials": {
        "openAiApi": {
          "id": "ICwxUBbatsF2sDvy",
          "name": "OpenAi account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// UNIVERSAL AI RESPONSE PARSER - Same code for ALL cases\nconst items = [];\nconst input = $input.all();\n\nfunction extractJSON(text) {\n  const jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\n  if (!jsonMatch) return null;\n  return jsonMatch[0];\n}\n\ninput.forEach((item, index) => {\n  try {\n    let aiText = item.json.output[0].content[0].text || '';\n    \n    // Clean markdown code blocks\n    aiText = aiText\n      .replace(/```json/gi, '')\n      .replace(/```/g, '')\n      .trim();\n    \n    // Extract JSON object\n    const jsonStr = extractJSON(aiText);\n    \n    if (!jsonStr) {\n      throw new Error('No JSON found in AI response');\n    }\n    \n    // Parse and return clean JSON\n    const parsed = JSON.parse(jsonStr);\n    items.push({ json: parsed });\n    \n  } catch (error) {\n    console.error(`Parse error for item ${index}:`, error.message);\n    // Return empty object on error - no case-specific fields\n    items.push({ json: {} });\n  }\n});\n\nreturn items;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        512,
        -160
      ],
      "id": "a083d3e3-a90a-472b-ad99-5cb4f7cd9c07",
      "name": "Parse AI Response"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "timestamp",
              "name": "analysis_timestamp",
              "value": "={{ new Date().toISOString() }}",
              "type": "string"
            },
            {
              "id": "company_name",
              "name": "company_name",
              "value": "={{ $('Get Dataset Items').item.json.author?.name || 'unknown' }}",
              "type": "string"
            },
            {
              "id": "company_profile",
              "name": "company_profile",
              "value": "={{ $('Get Dataset Items').item.json.author?.linkedinUrl || '' }}",
              "type": "string"
            },
            {
              "id": "job_title",
              "name": "job_title",
              "value": "={{ $json.job_title }}",
              "type": "string"
            },
            {
              "id": "seniority",
              "name": "seniority_level",
              "value": "={{ $json.seniority_level }}",
              "type": "string"
            },
            {
              "id": "department",
              "name": "department",
              "value": "={{ $json.department }}",
              "type": "string"
            },
            {
              "id": "skills",
              "name": "required_skills",
              "value": "={{ $json.required_skills }}",
              "type": "array"
            },
            {
              "id": "location_type",
              "name": "location_type",
              "value": "={{ $json.location_type }}",
              "type": "string"
            },
            {
              "id": "location_city",
              "name": "location_city",
              "value": "={{ $json.location_city }}",
              "type": "string"
            },
            {
              "id": "urgency",
              "name": "urgency_level",
              "value": "={{ $json.urgency_level }}",
              "type": "string"
            },
            {
              "id": "compensation",
              "name": "compensation_mentioned",
              "value": "={{ $json.compensation_mentioned }}",
              "type": "string"
            },
            {
              "id": "intel",
              "name": "competitive_intel",
              "value": "={{ $json.competitive_intel }}",
              "type": "string"
            },
            {
              "id": "post_content",
              "name": "post_content",
              "value": "={{ $('Get Dataset Items').item.json.content || '' }}",
              "type": "string"
            },
            {
              "id": "post_date",
              "name": "post_date",
              "value": "={{ $('Get Dataset Items').item.json.postedAt?.date || '' }}",
              "type": "string"
            },
            {
              "id": "post_url",
              "name": "post_url",
              "value": "={{ $('Get Dataset Items').item.json.linkedinUrl || '' }}",
              "type": "string"
            },
            {
              "id": "likes",
              "name": "likes_count",
              "value": "={{ $('Get Dataset Items').item.json.engagement?.likes || 0 }}",
              "type": "number"
            },
            {
              "id": "comments",
              "name": "comments_count",
              "value": "={{ $('Get Dataset Items').item.json.engagement?.comments || 0 }}",
              "type": "number"
            },
            {
              "id": "shares",
              "name": "shares_count",
              "value": "={{ $('Get Dataset Items').item.json.engagement?.shares || 0 }}",
              "type": "number"
            },
            {
              "id": "total_engagement",
              "name": "engagement_total",
              "value": "={{ ($('Get Dataset Items').item.json.engagement?.likes || 0) + ($('Get Dataset Items').item.json.engagement?.comments || 0) + ($('Get Dataset Items').item.json.engagement?.shares || 0) }}",
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        704,
        -160
      ],
      "id": "ce8e7106-13c5-4c8d-aec3-4fa6dd00aa1a",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "1E9cdTRB6J4yKJkrpkYEXdh1wCAodieUz6laM-yi1jmk",
          "mode": "list",
          "cachedResultName": "Case 76 - Job Market Intelligence Log",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1E9cdTRB6J4yKJkrpkYEXdh1wCAodieUz6laM-yi1jmk/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Sheet1",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1E9cdTRB6J4yKJkrpkYEXdh1wCAodieUz6laM-yi1jmk/edit#gid=0"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Analysis_Date": "={{ $json.analysis_timestamp }}",
            "Company_Name": "={{ $json.company_name }}",
            "Job_Title": "={{ $json.job_title }}",
            "Seniority_Level": "={{ $json.seniority_level }}",
            "Department": "={{ $json.department }}",
            "Required_Skills": "={{ $json.required_skills.join('; ') }}",
            "Location_Type": "={{ $json.location_type }}",
            "Location_City": "={{ $json.location_city }}",
            "Urgency_Level": "={{ $json.urgency_level }}",
            "Compensation_Mentioned": "={{ $json.compensation_mentioned }}",
            "Competitive_Intel": "={{ $json.competitive_intel }}",
            "Post_Date": "={{ $json.post_date }}",
            "Likes": "={{ $json.likes_count }}",
            "Comments": "={{ $json.comments_count }}",
            "Shares": "={{ $json.shares_count }}",
            "Total_Engagement": "={{ $json.engagement_total }}",
            "Post_URL": "={{ $json.post_url }}",
            "Post_Content": "={{ $json.post_content }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "Analysis_Date",
              "displayName": "Analysis_Date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Company_Name",
              "displayName": "Company_Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Job_Title",
              "displayName": "Job_Title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Seniority_Level",
              "displayName": "Seniority_Level",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Department",
              "displayName": "Department",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Required_Skills",
              "displayName": "Required_Skills",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Location_Type",
              "displayName": "Location_Type",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Location_City",
              "displayName": "Location_City",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Urgency_Level",
              "displayName": "Urgency_Level",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Compensation_Mentioned",
              "displayName": "Compensation_Mentioned",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Competitive_Intel",
              "displayName": "Competitive_Intel",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Post_Date",
              "displayName": "Post_Date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Likes",
              "displayName": "Likes",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Comments",
              "displayName": "Comments",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Shares",
              "displayName": "Shares",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Total_Engagement",
              "displayName": "Total_Engagement",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Post_URL",
              "displayName": "Post_URL",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Post_Content",
              "displayName": "Post_Content",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        896,
        -160
      ],
      "id": "e73544bd-2f3d-45d6-8991-edaf3d1a721d",
      "name": "Log to Google Sheet",
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "LOs2dbk9lby0NfDM",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Aggregate all items from Google Sheets into email-ready summary\nconst allItems = $input.all();\n\n// Count by department\nconst departmentCounts = {};\nallItems.forEach(item => {\n  const dept = item.json.Department || 'Other';\n  departmentCounts[dept] = (departmentCounts[dept] || 0) + 1;\n});\n\nconst departmentBreakdown = Object.entries(departmentCounts)\n  .sort((a, b) => b[1] - a[1]);\n\n// Count by seniority\nconst seniorityCounts = {};\nallItems.forEach(item => {\n  const seniority = item.json.Seniority_Level || 'Unclear';\n  seniorityCounts[seniority] = (seniorityCounts[seniority] || 0) + 1;\n});\n\n// Count by location type\nconst locationCounts = {};\nallItems.forEach(item => {\n  const locationType = item.json.Location_Type || 'Not specified';\n  locationCounts[locationType] = (locationCounts[locationType] || 0) + 1;\n});\n\n// Top skills mentioned\nconst skillCounts = {};\nallItems.forEach(item => {\n  const skillsString = item.json.Required_Skills || '';\n  if (skillsString) {\n    const skills = skillsString.split(';').map(s => s.trim()).filter(s => s);\n    skills.forEach(skill => {\n      skillCounts[skill] = (skillCounts[skill] || 0) + 1;\n    });\n  }\n});\n\nconst topSkills = Object.entries(skillCounts)\n  .sort((a, b) => b[1] - a[1])\n  .slice(0, 10)\n  .map(([skill, count]) => ({ skill, mentions: count }));\n\n// Top hiring companies\nconst companyCounts = {};\nallItems.forEach(item => {\n  const company = item.json.Company_Name || 'Unknown';\n  companyCounts[company] = (companyCounts[company] || 0) + 1;\n});\n\nconst topCompanies = Object.entries(companyCounts)\n  .sort((a, b) => b[1] - a[1])\n  .slice(0, 10)\n  .map(([company, count]) => ({ company, jobs: count }));\n\n// Compensation analysis\nconst compensationMentioned = allItems.filter(item => \n  item.json.Compensation_Mentioned && \n  item.json.Compensation_Mentioned.toLowerCase().includes('yes')\n).length;\n\nconst compensationPercentage = Math.round((compensationMentioned / allItems.length) * 100);\n\n// Urgent hiring count\nconst urgentJobs = allItems.filter(item => \n  item.json.Urgency_Level === 'Immediate'\n).length;\n\n// Build HTML table rows\nconst tableRows = allItems.map(item => {\n  const data = item.json;\n  \n  return `\n    <tr>\n      <td>${data.Company_Name || 'N/A'}</td>\n      <td>${data.Job_Title || 'N/A'}</td>\n      <td>${data.Department || 'N/A'}</td>\n      <td>${data.Seniority_Level || 'N/A'}</td>\n      <td>${data.Location_Type || 'N/A'}</td>\n      <td>${data.Urgency_Level || 'N/A'}</td>\n      <td><a href=\"${data.Post_URL || '#'}\">View</a></td>\n    </tr>\n  `;\n}).join('');\n\n// Return single aggregated item\nreturn {\n  json: {\n    week_start: new Date(Date.now() - 7*24*60*60*1000).toISOString().split('T')[0],\n    week_end: new Date().toISOString().split('T')[0],\n    total_jobs_analyzed: allItems.length,\n    department_breakdown: departmentBreakdown,\n    seniority_breakdown: Object.entries(seniorityCounts),\n    location_breakdown: Object.entries(locationCounts),\n    top_skills: topSkills,\n    top_companies: topCompanies,\n    compensation_percentage: compensationPercentage,\n    urgent_jobs_count: urgentJobs,\n    table_rows: tableRows,\n    all_jobs: allItems.map(item => item.json)\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1088,
        -160
      ],
      "id": "77f7ab8f-e0f9-40a1-b145-23bb568e241a",
      "name": "Aggregate Weekly Summary"
    },
    {
      "parameters": {
        "sendTo": "hiring-team@yourcompany.com",
        "subject": "=📊 Weekly Job Market Intelligence Report: {{ $json.week_start }} to {{ $json.week_end }}",
        "message": "=WEEKLY JOB MARKET INTELLIGENCE REPORT\n================================================\nReport Period: {{ $json.week_start }} to {{ $json.week_end }}\n\nOVERVIEW:\nTotal Job Postings Analyzed: {{ $json.total_jobs_analyzed }}\nUrgent Hiring Signals: {{ $json.urgent_jobs_count }}\nCompensation Mentioned: {{ $json.compensation_percentage }}% of postings\n\nTOP HIRING DEPARTMENTS:\n{{ $json.department_breakdown.slice(0, 5).map(([dept, count]) => dept + ': ' + count + ' positions').join('\\n') }}\n\nSENIORITY BREAKDOWN:\n{{ $json.seniority_breakdown.map(([level, count]) => level + ': ' + count).join('\\n') }}\n\nLOCATION TYPE DISTRIBUTION:\n{{ $json.location_breakdown.map(([type, count]) => type + ': ' + count).join('\\n') }}\n\nTOP 10 IN-DEMAND SKILLS:\n{{ $json.top_skills.map((skill, i) => (i+1) + '. ' + skill.skill + ' (' + skill.mentions + ' mentions)').join('\\n') }}\n\nTOP 10 HIRING COMPANIES:\n{{ $json.top_companies.map((company, i) => (i+1) + '. ' + company.company + ' (' + company.jobs + ' positions)').join('\\n') }}\n\nFull job details in Google Sheets.\n\nGenerated: {{ new Date().toLocaleDateString() }}",
        "options": {}
      },
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1280,
        -160
      ],
      "id": "cdc6aae6-4a0f-4e73-9bca-be9d3b474b3c",
      "name": "Send Weekly Summary Email",
      "webhookId": "4d2ba76c-a033-40d1-9d69-bcad351e74f4",
      "credentials": {
        "gmailOAuth2": {
          "id": "cyqCGWcggZNMcSOv",
          "name": "Gmail account"
        }
      }
    }
  ],
  "pinData": {},
  "connections": {
    "Weekly Schedule - Monday 9 AM": {
      "main": [
        [
          {
            "node": "Scrape LinkedIn Job Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape LinkedIn Job Posts": {
      "main": [
        [
          {
            "node": "Get Dataset Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Dataset Items": {
      "main": [
        [
          {
            "node": "AI Validation Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Validation Filter": {
      "main": [
        [
          {
            "node": "Parse AI Validation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Validation": {
      "main": [
        [
          {
            "node": "Edit Fields - Validation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields - Validation": {
      "main": [
        [
          {
            "node": "Filter Only Job Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Only Job Posts": {
      "main": [
        [
          {
            "node": "AI Extract Job Intelligence",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Extract Job Intelligence": {
      "main": [
        [
          {
            "node": "Parse AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Response": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Log to Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Google Sheet": {
      "main": [
        [
          {
            "node": "Aggregate Weekly Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Weekly Summary": {
      "main": [
        [
          {
            "node": "Send Weekly Summary Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "e9a6d40a-cbe2-49fe-bd4e-926c8afd3e42",
  "meta": {
    "instanceId": "3a43da28588548e21903e71cf1dc3ddd65c24bf0c62e7e4b77542ffe87ad79c6"
  },
  "id": "nJbUXIXdNzaQhzLD",
  "tags": []
}